package com.kh.statistics.video.core.statistics;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.kh.statistics.video.constant.PlatformConstant;
import com.kh.statistics.video.core.MediaContext;
import com.kh.statistics.video.core.Platform;
import com.kh.statistics.video.core.script.DefualtParseExecResult;
import com.kh.statistics.video.core.script.ShellExecutor;
import com.kh.statistics.video.core.statistics.entity.DouYinReq;
import com.kh.statistics.video.entity.DouYinShareUrl;
import com.kh.statistics.video.entity.StatisticsInfo;
import com.kh.statistics.video.entity.StatisticsMeta;
import com.kh.statistics.video.entity.StatisticsOne;
import com.kh.statistics.video.helper.ExcelHelper;
import com.kh.statistics.video.helper.NumberHelper;
import com.kh.statistics.video.helper.StatisticsHttpHelper;
import com.kh.statistics.video.utils.ParamsUtils;
import com.kh.statistics.video.utils.SerializationUtils;
import com.kh.statistics.video.utils.URIEncoder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * @ClassName DouYinPlatform
 * @Description TODO
 * @Author konghong1
 * @Date 2024/5/7 22:00
 * @Version 1.0
 **/
@Component
@Slf4j
public class DouYinPlatform implements Platform {

    private final static String defaultCursorPre = "max_cursor=";

    @Value("${statistics.platform.share.douyin.cmd}")
    private String cmd;

    @Value("${statistics.platform.share.douyin.path}")
    private String path;

    @Override
    public String support() {
        return PlatformConstant.DOU_YIN;
    }

    @Override
    public List<StatisticsInfo> getInfo(StatisticsMeta statisticsMeta) {
        return null;
    }

    /**
     * 统计总数据
     *
     * @param list
     */
    @Override
    public void statistics(List<StatisticsMeta> list) {
        List<StatisticsInfo> statisticsInfoListAll = new ArrayList<>();
        StatisticsInfo statisticsInfo = new StatisticsInfo();
        for (StatisticsMeta statisticsMeta : list) {
            String request = StatisticsHttpHelper.request(statisticsMeta);
            if ("dataPerformance".equals(statisticsMeta.getName())) {
                statisticsTotalDataPerformance(statisticsInfo, request);
            }
        }
        statisticsInfoListAll.add(statisticsInfo);
        ExcelHelper.export(ExcelHelper.getExcelName(list.get(0).getAccountName(), "抖音统计总"), statisticsInfoListAll, StatisticsInfo.class);

    }

    @Override
    public void oneStatistics(List<StatisticsMeta> statisticsMetaList, MediaContext mediaContext) {
        List<StatisticsOne> statisticsInfoListAll = new ArrayList<>();
        Map<String, StatisticsOne> map = new HashMap<>();
        DouYinReq douYinReq = null;
        //统计数据
        Optional<StatisticsMeta> statistics = statisticsMetaList.stream().filter((item) -> null != item.getName() && "statistics".equals(item.getName())).findFirst();
        if (statistics.isPresent()) {
            StatisticsMeta statisticsMeta = statistics.get();
            //{
            //  "start_date": "20240302",
            //  "end_date": "20240531"
            //}
            douYinReq = SerializationUtils.deserialize(statisticsMeta.getJsonParam(), DouYinReq.class);
            String body = StatisticsHttpHelper.request(statisticsMeta);
            if (!handlerResponse(body)) {
                return;
            }
            List<StatisticsOne> statisticsInfos = oneStatistics(body);
            statisticsInfos.forEach((item) -> {
                map.put(item.getAwemeId(), item);
            });
            statisticsInfoListAll.addAll(statisticsInfos);
        }

        Optional<StatisticsMeta> shareUrl = statisticsMetaList.stream().filter((item) -> null != item.getName() && "shareUrl".equals(item.getName())).findFirst();
        if (shareUrl.isPresent()) {
            StatisticsMeta statisticsMeta = shareUrl.get();
            String msToken = ParamsUtils.parseCookiesAndGet(mediaContext.getVideoAccountsLogin().getCookies(), "msToken");
            String body = StatisticsHttpHelper.request(statisticsMeta);
            List<DouYinShareUrl> shareUrlList = getShareUrlList(body);
            getShortShareUrl(shareUrlList, msToken);
            String startDate = douYinReq.getDataRange().getStartDate();
            //获取开始时间时间戳
            DateTime startDateParse = DateUtil.parse(startDate, "yyyyMMdd");
            long startTime = startDateParse.getTime();
            wrapShareUrl(shareUrlList, map);
            handlerShareUrl(startTime, msToken, body, statisticsMeta, 0L, map);
        }
        ExcelHelper.export(ExcelHelper.getExcelName(statisticsMetaList.get(0).getAccountName(), "抖音单条统计"), statisticsInfoListAll, StatisticsOne.class);
    }

    private void wrapShareUrl(List<DouYinShareUrl> shareUrlList, Map<String, StatisticsOne> map) {
        shareUrlList.forEach((item) -> {
            StatisticsOne statisticsOne = map.get(item.getAwemeId());
            if (null != statisticsOne) {
                if (StringUtils.isNotBlank(item.getShareTemplate())) {
                    String shareTemplate = item.getShareTemplate();
                    String[] splits = shareTemplate.split(" ");
                    List<String> newList = new ArrayList<>();
                    newList.add(splits[0]);
                    newList.addAll(Arrays.asList(splits).subList(4, splits.length));

                    newList.add(splits[1]);
                    newList.add(splits[3]);
                    newList.add(splits[2]);

                    String join = StringUtils.join(newList, " ");
                    String link = String.format(join, item.getShareUrl());
                    statisticsOne.setLink(link);
                    return;
                }
                statisticsOne.setLink(item.getShareUrl());
            }
        });
    }

    public void handlerShareUrl(long startTime, String msToken, String body, StatisticsMeta statisticsMeta, Long cursor, Map<String, StatisticsOne> map) {
        //解析body
        Long maxCursor = getMaxCursor(body);
        //先判断下url 是否已经完全替换
        Optional<String> any = map.keySet().stream().filter((item) -> StringUtils.isBlank(map.get(item).getLink())).findAny();
        if (any.isEmpty()) {
            return;
        }
        //进入循环则需要替换请求地址接着获取
        if (maxCursor != null && (maxCursor > startTime)) {
            String url = statisticsMeta.getUrl();
            String newUrl = url.replaceAll(defaultCursorPre + cursor, defaultCursorPre + maxCursor);
            statisticsMeta.setUrl(newUrl);
            String newBody = StatisticsHttpHelper.request(statisticsMeta);
            List<DouYinShareUrl> newShareUrlList = getShareUrlList(newBody);
            getShortShareUrl(newShareUrlList, msToken);
            wrapShareUrl(newShareUrlList, map);
            handlerShareUrl(startTime, msToken, newBody, statisticsMeta, maxCursor, map);
        }

    }

    @Override
    public boolean handlerResponse(String body) {
        return true;
    }


    private List<StatisticsOne> oneStatistics(String body) {
        List<StatisticsOne> itemList = new ArrayList<>();
        JSONObject jsonObject = JSONObject.parseObject(body);
        JSONArray array = jsonObject.getJSONArray("items");
        for (Object o : array) {
            StatisticsOne statisticsInfo = new StatisticsOne();
            JSONObject item = (JSONObject) o;
            String itemId = item.getString("item_id");
            statisticsInfo.setAwemeId(itemId);
            JSONObject itemInfo = item.getJSONObject("item_info");
            JSONObject baseInfo = itemInfo.getJSONObject("base_info");
            String publish_time = baseInfo.getString("publish_time");
            statisticsInfo.setPushDate(publish_time);
            String title = baseInfo.getString("title");
            statisticsInfo.setWorks(title);

            JSONObject metrics = itemInfo.getJSONObject("metrics");
            Long comment_count = metrics.getLong("comment_count");
            statisticsInfo.setCommentsNumber(comment_count);
            Long play_count = metrics.getLong("play_count");
            statisticsInfo.setExposure(play_count);
            Long like_count = metrics.getLong("like_count");
            statisticsInfo.setClicksNumber(like_count);
            double finish = metrics.getDouble("finish");
            statisticsInfo.setCompletionRate(NumberHelper.doubleFormat(finish));
            itemList.add(statisticsInfo);
        }
        return itemList;
    }

    private List<DouYinShareUrl> getShareUrlList(String body) {
        List<DouYinShareUrl> itemList = new ArrayList<>();
        JSONObject jsonObject = JSONObject.parseObject(body);
        JSONArray aweme_list = jsonObject.getJSONArray("aweme_list");
        for (Object o : aweme_list) {
            DouYinShareUrl douYinShareUrl = new DouYinShareUrl();
            JSONObject item = (JSONObject) o;
            String aweme_id = item.getString("aweme_id");
            String share_url = item.getString("share_url");
            JSONObject shareInfo = item.getJSONObject("share_info");
            if (null != shareInfo) {
                String shareLinkDesc = shareInfo.getString("share_link_desc");
                douYinShareUrl.setShareTemplate(shareLinkDesc);
            }
            douYinShareUrl.setUrl(share_url);
            douYinShareUrl.setAwemeId(aweme_id);
            itemList.add(douYinShareUrl);
        }
        return itemList;
    }

    private void getShortShareUrl(List<DouYinShareUrl> itemList, String msToken) {
        DefualtParseExecResult defualtParseExecResult = new DefualtParseExecResult();
        if (CollectionUtils.isEmpty(itemList) || StringUtils.isBlank(msToken)) {
            return;
        }
        itemList.forEach((item) -> {
            StatisticsMeta statisticsMeta = new StatisticsMeta();
            statisticsMeta.setRequestType("get");
            Map<String, String> paramMap = new LinkedHashMap<>();
            String encode = URIEncoder.encodeURIComponent(item.getUrl());
            log.info("原始url:{},encode:{}", item.getUrl(), encode);
            paramMap.put("target", encode);
            paramMap.put("belong", "aweme");
            paramMap.put("aid", "6383");
            paramMap.put("msToken", msToken);
            String a_bParams = ParamsUtils.withParams(paramMap);
            List<String> cmdList = ShellExecutor.parseScript(cmd);
            cmdList.add(ShellExecutor.parseParam(a_bParams));
            //获取a_bogus值
            Map<String, List<String>> retMap = ShellExecutor.executeScript(path, cmdList.toArray(new String[0]));
            String a_b = defualtParseExecResult.parse(retMap, "douyin=");
            paramMap.put("a_bogus", a_b);
            String params = ParamsUtils.withParams(paramMap);
            String shareUrl = HttpUtil.urlWithForm("https://www.douyin.com/aweme/v1/web/web_shorten/", params, StandardCharsets.UTF_8, false);
            log.info("shareUrl:【{}】", shareUrl);
            statisticsMeta.setUrl(shareUrl);
            Map<String, String> userAgentMap = new HashMap<>();
            userAgentMap.put("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 Edg/125.0.0.0");
            statisticsMeta.setHeaders(userAgentMap);
            String body = StatisticsHttpHelper.request(statisticsMeta);
            log.info("shareUrlReqResult:【{}】", body);
            JSONObject jsonObject = JSONObject.parseObject(body);
            Integer code = jsonObject.getInteger("code");
            if (0 == code) {
                item.setShareUrl(jsonObject.getString("data"));
            }
        });
    }


    private Long getMaxCursor(String body) {
        JSONObject jsonObject = JSONObject.parseObject(body);
        return jsonObject.getLong("max_cursor");
    }

    private void statisticsTotalDataPerformance(StatisticsInfo statisticsInfo, String body) {
        JSONObject jsonObject = JSONObject.parseObject(body);
        JSONArray metrics = jsonObject.getJSONArray("metrics");
        for (Object metric : metrics) {
            JSONObject item = (JSONObject) metric;
            String english_metric_name = item.getString("english_metric_name");
            Long metric_value = item.getLong("metric_value");
            if ("play_cnt".equalsIgnoreCase(english_metric_name)) {
                statisticsInfo.setPlaysNumber(metric_value);
            }
            if ("digg_cnt".equalsIgnoreCase(english_metric_name)) {
                statisticsInfo.setClicksNumber(metric_value);
            }
            //净增粉丝
            if ("net_fans_cnt".equalsIgnoreCase(english_metric_name)) {
                statisticsInfo.setIncreaseFollowersNumber(metric_value);
            }
            if ("total_fans_cnt".equalsIgnoreCase(english_metric_name)) {
                statisticsInfo.setTotalFollowersNumber(metric_value);
            }
        }
    }
}
